package entities.concept;


import domain.FeatureGraph;
import entities.role.Role;


/**
 * A chain/feature/attribute only contains functional roles (if (a,b)(a,c)then b=c).
 * In our case, features are simple ones, i.e., chain of length one
 * We currently allow f=k, f<= k and f<k as a concrete feature concept
 * @author J.W.Wu
 *
 */
public abstract class DomainConcept<S, T> extends Concept{

	protected S f = null;
	protected T k = null;
	
	public DomainConcept(S f, T k){
		this.f = f;
		this.k = k;
	}
	
	
	public int getOp(){
		int op = 2;
		if(this instanceof DomainConceptEQ){
			op = FeatureGraph.INTEQ;
		}else if(this instanceof DomainConceptLTEQ){
			op = FeatureGraph.INTLTEQ;
		}else if(this instanceof DomainConceptLT){
			op = FeatureGraph.INTLT;
		}
		return op;
	}
	
	public Object getRealFeature(){
		if(isLHSRole()){
			return this.f;
		}else if(isRHSRole()){
			return this.k;
		}else{
			System.err.println("No role in this domain concept, null returned: "+this.toString());
			return null;
		}
	}
	
	public Object getRealValue(){
		if(isLHSRole()){
			return this.k;
		}else if(isRHSRole()){
			return this.f;
		}else{
			System.err.println("No string found in this domain concept, null returned: "+this.toString());
			return null;
		}
	}
	
	public S getFeature(){
		return this.f;
	}
	
	public T getValue(){
		return this.k;
	}
	
	public boolean isLHSRole(){
		return this.f instanceof Role;
	}
	
	public boolean isRHSRole(){
		return this.k instanceof Role;
	}
	
	public boolean isLHSString(){
		return this.f instanceof String;
	}
	
	public boolean isRHSString(){
		return this.k instanceof String;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((f == null) ? 0 : f.hashCode());
		result = prime * result + ((k == null) ? 0 : k.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!(obj instanceof DomainConcept))
			return false;
		DomainConcept<?, ?> other = (DomainConcept<?, ?>) obj;
		if (f == null) {
			if (other.f != null)
				return false;
		} else if (!f.equals(other.f))
			return false;
		if (k == null) {
			if (other.k != null)
				return false;
		} else if (!k.equals(other.k))
			return false;
		return true;
	}	
	
}
